/*
 * attribute.h
 *
 *  Created on: Aug 14, 2013
 *      Author: killerg
 */

#ifndef ATTRIBUTE_H_
#define ATTRIBUTE_H_

#include "share/cs_msg.pb.h"
using namespace cs;

struct att_mod_t {
    EPetAtt att;
    int32_t flat_mod;
    int32_t pct_mod;

    att_mod_t(int32_t att, int32_t flat, int32_t pct) {
        this->att = EPetAtt(att);
        this->flat_mod = flat;
        this->pct_mod = pct;
    }
};

struct att_t {
    int32_t final[cs::EPetAtt_ARRAYSIZE];
    int32_t base[cs::EPetAtt_ARRAYSIZE];
    int32_t neg_pct_mod[cs::EPetAtt_ARRAYSIZE];
    int32_t neg_flat_mod[cs::EPetAtt_ARRAYSIZE];
    int32_t pos_flat_mod[cs::EPetAtt_ARRAYSIZE];
    int32_t pos_pct_mod[cs::EPetAtt_ARRAYSIZE];

    void add_mods(const list<pair<int32_t, int32_t>> &mods);
    void dec_mods(const list<pair<int32_t, int32_t>> &mods);

    void add_mod(int32_t modid, int32_t rate = 1);
    void dec_mod(int32_t modid, int32_t rate = 1);

    void add_mods(const vector<att_mod_t> &mods);
    void dec_mods(const vector<att_mod_t> &mods);

    void mod_pct(EPetAtt att, int32_t val, bool add) {
        if (add) {
            if (val > 0)
                pos_pct_mod[att] += val;
            else
                neg_pct_mod[att] += val;
        } else {
            if (val > 0)
                pos_pct_mod[att] -= val;
            else
                neg_pct_mod[att] -= val;
        }
    }

    void mod_flat(EPetAtt att, int32_t val, bool add) {
        if (add) {
            if (val > 0)
                pos_flat_mod[att] += val;
            else
                neg_flat_mod[att] += val;
        } else {
            if (val > 0)
                pos_flat_mod[att] -= val;
            else
                neg_flat_mod[att] -= val;
        }
    }

    void calc() {
        for (int i=int(cs::EPetAtt_MIN); i<=int(cs::EPetAtt_MAX); ++i) {
            final[i] = (base[i] + pos_flat_mod[i] + neg_flat_mod[i]) * (1.0 + (pos_pct_mod[i] + neg_pct_mod[i]) / 9999.0f);
        }
    }

    void reset() {
        memset(this, 0, sizeof(*this));
    }
    int32_t get(EPetAtt att) const {
        return final[att];
    }
    bool init(const int32_t att[CanSeePetAttNum]) {
        memset(base, 0, sizeof(base));
        memset(final, 0, sizeof(final));
        memset(base, 0, sizeof(base));
        memset(neg_pct_mod, 0, sizeof(neg_pct_mod));
        memset(neg_flat_mod, 0, sizeof(neg_flat_mod));
        memset(pos_flat_mod, 0, sizeof(pos_flat_mod));
        memset(pos_pct_mod, 0, sizeof(pos_pct_mod));

        for (int i=0; i<CanSeePetAttNum; ++i)
            base[i] = att[i];

        return true;
    }
    void destroy() {
        static int32_t a[] = {0,0,0,0};
        init(a);
    }
};

#endif /* ATTRIBUTE_H_ */
